
export interface CodecType {

    encode(buf: number[], index: number): void;
    decode(buf: number[], index: number): void;
    size(): number;
}

export class Uint8 implements CodecType {

    value: number;

    constructor(v: number = 0) {
        this.value = v;
    }

    encode(buf: number[], index: number): void {
        buf[index] = this.value & 0xFF;
    }

    decode(buf: number[], index: number): void {
        this.value = buf[index];
    }

    size(): number {
        return 1;
    }
}

export class Uint16 implements CodecType {
    value: number;

    constructor(v: number = 0) {
        this.value = v;
    }

    encode(buf: number[], index: number): void {
        buf[index] = (this.value >> 8) & 0xFF;
        buf[index + 1] = this.value & 0xFF;
    }

    decode(buf: number[], index: number): void {
        this.value = (buf[index] << 8) +
            buf[index + 1];
    }

    size(): number {
        return 2;
    }
}

export class Uint32 implements CodecType {
    value: number;

    constructor(v: number = 0) {
        this.value = v;
    }

    encode(buf: number[], index: number): void {
        buf[index] = (this.value >> 24) & 0xFF;
        buf[index + 1] = (this.value >> 16) & 0xFF;
        buf[index + 2] = (this.value >> 8) & 0xFF;
        buf[index + 3] = this.value & 0xFF;
    }

    decode(buf: number[], index: number): void {
        this.value = (buf[index] << 24) +
            (buf[index + 1] << 16) +
            (buf[index + 2] << 8) +
            buf[index + 3];
    }

    size(): number {
        return 4;
    }
}

export class ByteView implements CodecType {

    value: number[] | Uint8Array;
    offset: number;
    len: number;

    constructor(buf: number[] | Uint8Array = [], offset: number = 0, len: number = buf.length - offset) {
        this.value = buf;
        this.offset = offset;
        this.len = len;
    }

    encode(buf: number[], index: number): void {
        buf[index] = this.len & 0xFF;
        for (let i = 0; i < this.len; i ++) {
            buf[index + 1 + i] = this.value[this.offset + i];
        }
    }

    decode(buf: number[], index: number): void {
        this.value = buf;
        this.offset = index + 1;
        this.len = buf[index];
    }

    size(): number {
        return this.len + 1;
    }

    toString() {
        let tc = new TextDecoder('utf8');
        return tc.decode( Uint8Array.from(this.value.slice( this.offset, this.offset + this.len )) );
    }
}




